package com.tqk.taxismart.distance;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;

import org.json.JSONObject;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMapClickListener;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.PolylineOptions;
import com.tqk.constant.Constant;
import com.tqk.taxismart.R;
import com.tqk.taxismart.obj.CheckPoint;

@SuppressLint("NewApi")
public class DistanceActivity extends Activity implements OnClickListener {
    private double currentLat, currentLng;
    private LatLng currentLaglng;
    private LocationManager locationManager;
    private String provider;
    private GoogleMap map;
    
    GPSTracker gps;
    Geocoder geocoder;
    List<Address> addresses;
    CheckPoint chkA, chkB;
    boolean flagA = false;
    boolean flagB = false;
    double distance;
    TextView txtStart, txtEnd;
    AlertDialog dialog;

    Button btnStart, btnEnd, btnClear;

    String minEstimate, maxEstimate;

    @SuppressLint("NewApi")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(com.tqk.taxismart.R.layout.distance_layout);
	btnStart = (Button) findViewById(R.id.btnLocationStart_id);
	btnEnd = (Button) findViewById(R.id.btnLocationEnd_id);
	txtStart = (TextView) findViewById(R.id.txtStart_id);
	txtEnd = (TextView) findViewById(R.id.txtEnd_id);
	btnClear = (Button)findViewById(R.id.btnClear_id);
	btnStart.setOnClickListener(this);
	btnEnd.setOnClickListener(this);
	btnClear.setOnClickListener(this);
	
	map = ((MapFragment)getFragmentManager().findFragmentById(R.id.map)).getMap();
	
	getCurrentLocation();
	currentLaglng = new LatLng(currentLat, currentLng);

	Marker kiel = map.addMarker(new MarkerOptions()
		.position(currentLaglng)
		.title("KhanhTQ")
		.snippet("'m here!")
		.icon(BitmapDescriptorFactory
			.fromResource(R.drawable.icon_green)));

	// Move the camera instantly to hamburg with a zoom of 15.
	map.moveCamera(CameraUpdateFactory.newLatLngZoom(currentLaglng, 25));
	
	// Zoom in, animating the camera.
	map.animateCamera(CameraUpdateFactory.zoomTo(15), 4000, null);
	geocoder = new Geocoder(DistanceActivity.this, Locale.getDefault());

	map.setOnMapClickListener(new OnMapClickListener() {

	    @Override
	    public void onMapClick(LatLng point) {
		System.out.println("lat = " + point.latitude);

		try {
			
		    addresses = geocoder.getFromLocation(point.latitude,point.longitude, 1);
		   
		} catch (IOException e) {
		    // TODO Auto-generated catch block
		    e.printStackTrace();
		}
		
		if (chkA != null && chkB != null) {
//		    showAlertMsg("Alert", "Limited ");
		}else{
		    if (flagA && chkA == null) {
			    chkA = addCheckpoint(point);
			    txtStart.setText(chkA.getAddress());
			}
			if (flagB && chkB == null) {
			    chkB = addCheckpoint(point);
			    txtEnd.setText(chkB.getAddress());
			}
		}
		
		
		
		

		System.out.println("flagA = " + flagA);
		System.out.println("flagB = " + flagB);
		if (chkA != null && chkB != null) {
		    // double xx = getDistanceAB(chkA, chkB);
		    runOnUiThread(new Runnable() {

			@Override
			public void run() {
			    LatLng A = new LatLng(chkA.getLat(), chkA.getLng());
			    LatLng B = new LatLng(chkB.getLat(), chkB.getLng());

			    String url = getDirectionsUrl(A, B);

			    DownloadTask downloadTask = new DownloadTask();

			    downloadTask.execute(url);
			}
		    });

		}
	    }
	});

    }

    private void getCurrentLocation() {
	gps = new GPSTracker(DistanceActivity.this);
	if (gps.canGetLocation()) {
	    currentLat = gps.getLatitude();
	    currentLng = gps.getLongitude();
	    System.out.println("LAT = " + currentLat);
	    System.out.println("Lng = " + currentLng);
	} else {
	    gps.showSettingsAlert();
	}
    }

    private CheckPoint addCheckpoint(final LatLng point) {

	CheckPoint chk = new CheckPoint();
	chk.setLat(point.latitude);
	chk.setLng(point.longitude);
	String address = "" ;
	try {
		
		 address = addresses.get(0).getAddressLine(0) + ","
				+ addresses.get(0).getAddressLine(1) + ","
				+ addresses.get(0).getAddressLine(2);
	} catch (Exception e) {
		// TODO: handle exception
	}
	chk.setAddress(address);

	// add maker on map
	Marker kiel = map.addMarker(new MarkerOptions()
		.position(new LatLng(point.latitude, point.longitude))
		.title("Location")
		.snippet(address)
		.icon(BitmapDescriptorFactory
			.fromResource(R.drawable.icon_green)));
	return chk;
    }

    private double getDistanceAB(CheckPoint A, CheckPoint B) {
	Location locationA = new Location("A");
	Location locationB = new Location("B");

	locationA.setLatitude(A.getLat());
	locationA.setLongitude(A.getLng());

	locationB.setLatitude(B.getLat());
	locationB.setLongitude(B.getLng());

	distance = locationA.distanceTo(locationB);
	return distance;
    }

    @Override
    public void onClick(View v) {
	int key = v.getId();
	switch (key) {
	case R.id.btnLocationStart_id:
	    flagA = true;
	    flagB = false;

	    break;
	case R.id.btnLocationEnd_id:
	    flagA = false;
	    flagB = true;
	    break;
	case R.id.btnClear_id:
	    map.clear();
	    chkA = null;
	    chkB = null;
	    flagA = false;
	    flagB = false;
	    txtStart.setText("");
	    txtEnd.setText("");
	    break;
	default:
	    break;
	}

    }

    private void showAlertMsg(String title, String msg) {
		AlertDialog.Builder builder = new AlertDialog.Builder(
				DistanceActivity.this);
		builder.setTitle(title + " km");
		builder.setMessage(msg)
				.setCancelable(false)
				.setPositiveButton("View",
						new DialogInterface.OnClickListener() {

							@Override
							public void onClick(DialogInterface dialog,
									int which) {
								System.out.println("---distance = "
										+ Constant.DISTANCE);
								Intent ii = new Intent(DistanceActivity.this,
										DetailEstimate.class);
								ii.putExtra("distance_km", Constant.DISTANCE);
								startActivity(ii);
							}
						})
				.setNegativeButton("No", new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {

					}
				});
		dialog = builder.create();
		if (!dialog.isShowing()) {
			dialog.show();
		}
	}
    
    private String getDirectionsUrl(LatLng origin, LatLng dest) {

	// Origin of route
	String str_origin = "origin=" + origin.latitude + ","
		+ origin.longitude;

	// Destination of route
	String str_dest = "destination=" + dest.latitude + "," + dest.longitude;

	// Sensor enabled
	String sensor = "sensor=false";

	// Building the parameters to the web service
	String parameters = str_origin + "&" + str_dest + "&" + sensor;

	// Output format
	String output = "json";

	String url = "https://maps.googleapis.com/maps/api/directions/"
		+ output + "?" + parameters;

	return url;
    }

    private String downloadUrl(String strUrl) throws IOException {
	String data = "";
	InputStream iStream = null;
	HttpURLConnection urlConnection = null;
	try {
	    URL url = new URL(strUrl);

	    urlConnection = (HttpURLConnection) url.openConnection();

	    // Connecting to url
	    urlConnection.connect();

	    // Reading data from url
	    iStream = urlConnection.getInputStream();

	    BufferedReader br = new BufferedReader(new InputStreamReader(
		    iStream));

	    StringBuffer sb = new StringBuffer();

	    String line = "";
	    while ((line = br.readLine()) != null) {
		sb.append(line);
	    }

	    data = sb.toString();

	    br.close();

	} catch (Exception e) {
	    Log.d("Exception while downloading url", e.toString());
	} finally {
	    iStream.close();
	    urlConnection.disconnect();
	}
	return data;
    }

    // Fetches data from url passed
    private class DownloadTask extends AsyncTask<String, Void, String> {

	// Downloading data in non-ui thread
	@Override
	protected String doInBackground(String... url) {

	    // For storing data from web service
	    String data = "";

	    try {
		// Fetching the data from web service
		data = downloadUrl(url[0]);
	    } catch (Exception e) {
		Log.d("Background Task", e.toString());
	    }
	    return data;
	}

	// Executes in UI thread, after the execution of
	// doInBackground()
	@Override
	protected void onPostExecute(String result) {
	    super.onPostExecute(result);

	    ParserTask parserTask = new ParserTask();

	    // Invokes the thread for parsing the JSON data
	    parserTask.execute(result);
	}
    }

    private class ParserTask extends
	    AsyncTask<String, Integer, List<List<HashMap<String, String>>>> {

	protected List<List<HashMap<String, String>>> doInBackground(
		String... jsonData) {

	    JSONObject jObject;
	    List<List<HashMap<String, String>>> routes = null;

	    try {
		jObject = new JSONObject(jsonData[0]);
		DirectionsJSONParser parser = new DirectionsJSONParser();

		// Starts parsing data
		routes = parser.parse(jObject);
	    } catch (Exception e) {
		e.printStackTrace();
	    }
	    return routes;
	}

	protected void onPostExecute(List<List<HashMap<String, String>>> result) {
	    ArrayList<LatLng> points = null;
	    PolylineOptions lineOptions = null;
	    MarkerOptions markerOptions = new MarkerOptions();

	    // Traversing through all the routes
	    for (int i = 0; i < result.size(); i++) {
		points = new ArrayList<LatLng>();
		lineOptions = new PolylineOptions();

		// Fetching i-th route
		List<HashMap<String, String>> path = result.get(i);

		// Fetching all the points in i-th route
		for (int j = 0; j < path.size(); j++) {
		    HashMap<String, String> point = path.get(j);

		    double lat = Double.parseDouble(point.get("lat"));
		    double lng = Double.parseDouble(point.get("lng"));
		    LatLng position = new LatLng(lat, lng);

		    points.add(position);
		}

		// Adding all the points in the route to LineOptions
		lineOptions.addAll(points);
		lineOptions.width(4);
		lineOptions.color(Color.BLUE);
	    }

	    // Drawing polyline in the Google Map for the i-th route
	    map.addPolyline(lineOptions);
	    estimate();
	    showAlertMsg(Constant.DISTANCE, "từ:" + minEstimate + "-"
		    + maxEstimate + ".000 vnd");

	}
    }

    private void estimate() {
	double dist = Double.valueOf(Constant.DISTANCE);
	Constant.DATA_TAXI = Constant.parserData(DistanceActivity.this);
	Constant.sortByPrice(Constant.DATA_TAXI);
	double estime1 = (double) Math.round(Constant.DATA_TAXI.get(0)
		.getPrice2() * Double.valueOf(Constant.DISTANCE) * 100) / 100;
	double estime2 = (double) Math.round(Constant.DATA_TAXI.get(
		Constant.DATA_TAXI.size() - 1).getPrice2()
		* Double.valueOf(Constant.DISTANCE) * 100) / 100;
	minEstimate = String.valueOf(estime1);
	maxEstimate = String.valueOf(estime2);
	Log.i("esimate1 = ", minEstimate);
	Log.i("esimate2 = ", maxEstimate);
    }

}
